package demo.db.mybatis;

import java.io.IOException;
import java.io.Reader;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MybatisUtil {

    private MybatisUtil() {
        super();
    }

    static Logger logger = LoggerFactory.getLogger(MybatisUtil.class);

    /**
     * 每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的。SqlSessionFactory 的实例可以通过
     * SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先定制的
     * Configuration 的实例构建出 SqlSessionFactory 的实例。
     * <p>
     * 从 XML 文件中构建 SqlSessionFactory
     * 的实例非常简单，建议使用类路径下的资源文件进行配置。但是也可以使用任意的输入流(InputStream)实例， 包括字符串形式的文件路径或者
     * file:// 的 URL形式的文件路径来配置。MyBatis 包含一个名叫 Resources 的工具类，它包含一些实用方法，可使从 classpath
     * 或其他位置加载资源文件更加容易。
     * 
     * <h2>SqlSessionFactoryBuilder</h2>
     * 每一个MyBatis的应用程序的入口是SqlSessionFactoryBuilder，它的作用是通过XML配置文件创建Configuration对象（当然也可以在程序中自行创建），
     * 然后通过build方法创建SqlSessionFactory对象。没有必要每次访问Mybatis就创建一次SqlSessionFactoryBuilder，通常的做法是创建一个全局的对象就可以了。
     * 这个类可以被实例化、使用和丢弃，一旦创建了 SqlSessionFactory，就不再需要它了。因此 SqlSessionFactoryBuilder
     * 实例的最佳作用域是方法作用域（也就是局部方法变量）。
     * 
     * <h2>SqlSessionFactory</h2> SqlSessionFactory对象由SqlSessionFactoryBuilder创建。
     * 它的主要功能是创建SqlSession对象，和SqlSessionFactoryBuilder对象一样，没有必要每次访问Mybatis就创建一次SqlSessionFactory，通常的做法是创建一个全局的对象就可以了。
     * 因此SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到，最简单的就是使用单例模式或者静态单例模式。
     * SqlSessionFactory对象一个必要的属性是Configuration对象,它是保存Mybatis全局配置的一个配置对象，通常由SqlSessionFactoryBuilder从XML配置文件创建。
     * 
     * @param filePath
     * @return
     * @throws IOException
     */
    public static SqlSessionFactory buildSqlSessionFactory(String filePath) throws IOException {
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        // 使用类加载器加载mybatis的配置文件（它也加载关联的映射文件）
        try (Reader reader = Resources.getResourceAsReader(filePath)) {
            // 构建sqlSession的工厂
            return sqlSessionFactoryBuilder.build(reader);
        }
    }

}
